package com.atguigu.product.controller;

import com.atguigu.vo.SearchVO;
import com.atguigu.order.OrderFeignClient;
import com.atguigu.product.bean.OrderProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/product")
@SuppressWarnings("all")
@RefreshScope
public class ProductController {

    @Autowired
    private OrderFeignClient orderFeignClient;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    DiscoveryClient discoveryClient;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @Value("${product.name:}")
    private String productName;

    @Autowired
    private OrderProperties orderProperties;


    /**
     * 远程调用1：使用RestTemplate
     *
     * @return
     */
    @GetMapping("/getOrderByRestTemplate")
    public String getOrderByRestTemplate() {
        log.info("getOrderByRestTemplate 调用 order 服务");
        List<ServiceInstance> instances = discoveryClient.getInstances("service-order");
        String host = "";
        int port = 0;
        for (ServiceInstance instance : instances) {
            host = instance.getHost();
            port = instance.getPort();
            continue;
        }

        String url = "http://" + host + ":" + port + "/order/get";
        log.info("请求url:{}", url);
        String order = restTemplate.getForObject(url, String.class);

        return order;
    }

    /**
     * 远程调用2升级：使用负载均衡
     *
     * @return
     */
    @GetMapping("/getOrderByLoadBalance")
    public String getOrderByLoadBalance() {
        log.info("getOrderByLoadBalance 调用 order 服务");
        ServiceInstance serviceInstance = loadBalancerClient.choose("service-order");
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        String url = "http://" + host + ":" + port + "/order/get";
        log.info("请求url:{}", url);
        String order = restTemplate.getForObject(url, String.class);

        return order;
    }

    /**
     * 远程调用3：基于注解版的负载均衡
     *
     * @return
     */
    @GetMapping("/getOrderByFeign")
    public String getOrderByFeign() {
        log.info("getOrderByFeign 调用 order 服务");
        return restTemplate.getForObject("http://service-order/order/get", String.class);
    }

    /**
     * 远程调用4：基于OpenFeign
     *
     * @return
     */
    @GetMapping("/getOrder")
    public String getOrder() {
        log.info("getOrder 调用 order 服务");
        return orderFeignClient.getOrder();
    }
    @GetMapping("/getOrder2")
    public String getOrder2() {
        log.info("getOrder2 调用 order 服务");
        return orderFeignClient.getOrder2(666L);
    }
    @GetMapping("/getOrder3")
    public String getOrder3() {
        log.info("getOrder3 调用 order 服务");
        return orderFeignClient.getOrder3(666L);
    }
    @GetMapping("/getOrder4")
    public String getOrder4() {
        log.info("getOrder4 调用 order 服务");
        SearchVO searchVO = new SearchVO();
        searchVO.setId(666L);
        return orderFeignClient.getOrder4(searchVO);
    }



    @GetMapping("/get")
    public String get() {
        return "通过openfeign 远程 调用 product 服务";
    }



    /**
     * 动态刷新1：通过nacos配置中心动态刷新配置
     */
    @GetMapping("/getConfig")
    public String getProduct() {
        log.info("动态刷新  getConfig");
        return productName;
    }

    /**
     * 动态刷新2
     */
    @GetMapping("/getConfig2")
    public String getOrderConfig() {
        log.info("动态刷新 getConfig2");
        return orderProperties.toString();
    }
}
